<template>
  <n-modal
    :title="`分配 ${role?.name} 的菜单权限`"
    v-model:show="show"
    preset="dialog"
    :show-icon="false"
  >
    <n-spin :show="!!treeLoading">
      <n-tree
        v-model:expanded-keys="expandedKeys"
        :checked-keys="checkedKeys"
        block-line
        checkable
        virtual-scroll
        expand-on-click
        :data="menuTree"
        style="max-height: 500px"
        @update:checked-keys="onCheckedUpdate"
      />
    </n-spin>
    <template #action>
      <n-space>
        <n-button type="info" ghost icon-placement="left" @click="handlePack">
          全部{{ expandedKeys.length ? "收起" : "展开" }}
        </n-button>

        <n-button type="info" ghost @click="handleReset"> 重置 </n-button>
        <n-button type="primary" :loading="btnLoading" @click="handleSubmit">
          提交
        </n-button>
      </n-space>
    </template>
  </n-modal>
</template>

<script lang="ts" setup>
import { roleApi } from "@/api";
import { cloneDeep } from "@/utils";
import { useGetMenuTree, useGetRolePerms, useCheckUpdate } from "./common";

const props = defineProps<{ role?: Role }>();

const show = ref(false);
const treeLoading = ref(0);
const btnLoading = ref(false);

const { menuTree, allTreeKeys, getMenuTree } = useGetMenuTree(treeLoading);

const { expandedKeys, checkedKeys, checkedKeysTemp } = useGetRolePerms(
  props,
  treeLoading
);

const { onCheckedUpdate } = useCheckUpdate(checkedKeys);

const handlePack = () => {
  if (expandedKeys.value.length) {
    expandedKeys.value = [];
  } else {
    expandedKeys.value = cloneDeep(allTreeKeys.value);
  }
};
const handleReset = () => {
  checkedKeys.value = cloneDeep(checkedKeysTemp.value);
};
const handleSubmit = async () => {
  if (!props.role?.id) return;
  btnLoading.value = true;
  try {
    const { status } = await roleApi.assignPerms(
      props.role.id,
      checkedKeys.value
    );
    if (status) {
      show.value = false;
      window.$message.success("分配成功");
    }
  } finally {
    btnLoading.value = false;
  }
};

getMenuTree();

const funShow = () => (show.value = true);
defineExpose({ show: funShow });
</script>
